home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / proc.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  14KB  |  649 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /* routines for handling processes */
  8.  
  9. #include "mint.h"
  10. #include "xbra.h"
  11.  
  12. static void do_wakeup_things P_((void));
  13.  
  14. extern short proc_clock;
  15.  
  16. /* global process variables */
  17. PROC *proclist;            /* list of all active processes */
  18. PROC *curproc;            /* current process        */
  19. PROC *rootproc;            /* pid 0 -- MiNT itself        */
  20. PROC *sys_q[NUM_QUEUES];
  21.  
  22. short time_slice = 2;        /* default; actual value comes from mint.cnf */
  23.  
  24. #if 0
  25. #define TIME_SLICE    2    /* number of 20ms ticks before process is
  26.                    pre-empted */
  27. #else
  28. #define TIME_SLICE time_slice
  29. #endif
  30.  
  31. /* macro for calculating number of missed time slices, based on a
  32.  * process' priority
  33.  */
  34. #define SLICES(pri)    (((pri) >= 0) ? 0 : -(pri))
  35.  
  36. extern FILESYS bios_filesys;
  37.  
  38. /*
  39.  * get a new process struct
  40.  */
  41.  
  42. PROC *
  43. new_proc()
  44. {
  45.     PROC *p;
  46.     void *pt;
  47.  
  48.     pt = kmalloc(page_table_size + 16);
  49.     if (!pt) return 0;
  50.  
  51.     p = (PROC *)kmalloc(SIZEOF(PROC));
  52.     if (!p) {
  53.         kfree(pt);
  54.         return 0;
  55.     }
  56. /* page tables must be on 16 byte boundaries, so we
  57.  * round off by 16 for that; however, we will want to
  58.  * kfree that memory at some point, so we squirrel
  59.  * away the original address for later use
  60.  */
  61.     p->page_table = ROUND16(pt);
  62.     p->pt_mem = pt;
  63.     return p;
  64. }
  65.  
  66. /*
  67.  * dispose of an old proc
  68.  */
  69.  
  70. void
  71. dispose_proc(p)
  72.     PROC *p;
  73. {
  74. TRACELOW(("dispose_proc"));
  75.     kfree(p->pt_mem);
  76.     kfree(p);
  77. }
  78.  
  79. /*
  80.  * create a new process that is (practically) a duplicate of the
  81.  * current one
  82.  */
  83.  
  84. PROC *
  85. fork_proc()
  86. {
  87.     PROC *p;
  88.     int i;
  89.     FILEPTR *f;
  90.     long_desc *pthold;
  91.     void *ptmemhold;
  92.  
  93.     if ((p = new_proc()) == 0) {
  94. nomem:
  95.         DEBUG(("fork_proc: insufficient memory"));
  96.         mint_errno = ENSMEM; return 0;
  97.     }
  98.  
  99. /* child shares most things with parent, but hold on to page table ptr */
  100.     pthold = p->page_table;
  101.     ptmemhold = p->pt_mem;
  102.     *p = *curproc;
  103.     p->page_table = pthold;
  104.     p->pt_mem = ptmemhold;
  105.  
  106. /* these things are not inherited */
  107.     p->ppid = curproc->pid;
  108.     p->pid = newpid();
  109.     p->sigpending = 0;
  110.     p->sysstack = (long)(p->stack + STKSIZE - 12);
  111.     p->ctxt[CURRENT].ssp = p->sysstack;
  112.     p->ctxt[SYSCALL].ssp = (long)(p->stack + ISTKSIZE);
  113.     p->alarmtim = 0;
  114.     p->curpri = p->pri;
  115.     p->slices = SLICES(p->pri);
  116.     p->starttime = timestamp;
  117.     p->startdate = datestamp;
  118.  
  119.     ((long *)p->sysstack)[1] = FRAME_MAGIC;
  120.     ((long *)p->sysstack)[2] = 0;
  121.     ((long *)p->sysstack)[3] = 0;
  122.  
  123.     p->usrtime = p->systime = p->chldstime = p->chldutime = 0;
  124.  
  125. /* copy open handles */
  126.     for (i = MIN_HANDLE; i < MAX_OPEN; i++) {
  127.         if ((f = p->handle[i]) != 0) {
  128.             if (f->flags & O_NOINHERIT)
  129.         /* oops, we didn't really want to copy this handle */
  130.                 p->handle[i] = 0;
  131.             else
  132.                 f->links++;
  133.         }
  134.     }
  135.  
  136. /* copy root and current directories */
  137.     for (i = 0; i < NUM_DRIVES; i++) {
  138.         dup_cookie(&p->root[i], &curproc->root[i]);
  139.         dup_cookie(&p->curdir[i], &curproc->curdir[i]);
  140.     }
  141.  
  142. /* clear directory search info */
  143.     zero((char *)p->srchdta, NUM_SEARCH * SIZEOF(DTABUF *));
  144.     p->searches = 0;
  145.  
  146. /* copy memory */
  147.     p->mem = (MEMREGION **) kmalloc(p->num_reg * SIZEOF(MEMREGION *));
  148.     if (!p->mem) {
  149.         dispose_proc(p);
  150.         goto nomem;
  151.     }
  152.     p->addr = (virtaddr *)kmalloc(p->num_reg * SIZEOF(virtaddr));
  153.     if (!p->addr) {
  154.         kfree(p->mem);
  155.         dispose_proc(p);
  156.         goto nomem;
  157.     }
  158.  
  159.     for (i = 0; i < curproc->num_reg; i++) {
  160.         p->mem[i] = curproc->mem[i];
  161.         if (p->mem[i] != 0)
  162.             p->mem[i]->links++;
  163.         p->addr[i] = curproc->addr[i];
  164.     }
  165.  
  166. /* now that memory ownership is copied, fill in page table */
  167.     init_page_table(p);
  168.  
  169. /* child isn't traced */
  170.     p->ptracer = 0;
  171.     p->ptraceflags = 0;
  172.  
  173.     p->starttime = Tgettime();
  174.     p->startdate = Tgetdate();
  175.  
  176.     p->q_next = 0;
  177.     p->wait_q = 0;
  178.     p->gl_next = proclist;
  179.     proclist = p;            /* hook into the process list */
  180.     return p;
  181. }
  182.  
  183. /*
  184.  * initialize the process table
  185.  */
  186.  
  187. void
  188. init_proc()
  189. {
  190.     int i;
  191.     FILESYS *fs;
  192.     fcookie dir;
  193.     long_desc *pthold;
  194.     void *ptmemhold;
  195.  
  196.     rootproc = curproc = new_proc();
  197.     assert(curproc);
  198.  
  199.     pthold = curproc->page_table;
  200.     ptmemhold = curproc->pt_mem;
  201.     zero((char *)curproc, (long)sizeof(PROC));
  202.     curproc->page_table = pthold;
  203.     curproc->pt_mem = ptmemhold;
  204.  
  205.     curproc->ppid = -1;        /* no parent */
  206.     curproc->domain = DOM_TOS;    /* TOS domain */
  207.     curproc->sysstack = (long) (curproc->stack+STKSIZE-12);
  208.     curproc->magic = CTXT_MAGIC;
  209.     curproc->memflags = F_PROT_S;    /* default prot mode: super-only */
  210.     ((long *)curproc->sysstack)[1] = FRAME_MAGIC;
  211.     ((long *)curproc->sysstack)[2] = 0;
  212.     ((long *)curproc->sysstack)[3] = 0;
  213.  
  214. /* NOTE: in main.c this could be changed, later */
  215.     curproc->base = _base;
  216.  
  217.     strcpy(curproc->name, "MiNT");
  218.  
  219. /* get some memory */
  220.     curproc->mem = (MEMREGION **)kmalloc(NUM_REGIONS*SIZEOF(MEMREGION *));
  221.     curproc->addr = (virtaddr *)kmalloc(NUM_REGIONS*SIZEOF(virtaddr));
  222.     assert(curproc->mem && curproc->addr);
  223.  
  224. /* make sure it's filled with zeros */
  225.     zero((char *)curproc->addr, NUM_REGIONS * SIZEOF(virtaddr));
  226.     zero((char *)curproc->mem, NUM_REGIONS * SIZEOF(MEMREGION *));
  227.     curproc->num_reg = NUM_REGIONS;
  228.  
  229. /* get root and current directories for all drives */
  230.     for (i = 0; i < NUM_DRIVES; i++) {
  231.         if ((fs = drives[i]) != 0 && (*fs->root)(i, &dir) == E_OK) {
  232.                 dup_cookie(&curproc->curdir[i], &dir);
  233.                 curproc->root[i] = dir;
  234.         } else {
  235.             curproc->root[i].fs = curproc->curdir[i].fs = 0;
  236.             curproc->root[i].dev = curproc->curdir[i].dev = i;
  237.         }
  238.     }
  239.  
  240.     init_page_table(curproc);
  241.  
  242. /* Set the correct drive. The current directory we
  243.  * set later, after all file systems have been loaded.
  244.  */
  245.  
  246.     curproc->curdrv = Dgetdrv();
  247.     proclist = curproc;
  248.  
  249.     curproc->umask = 0;
  250.  
  251. /*
  252.  * some more protection against job control; unless these signals are
  253.  * re-activated by a shell that knows about job control, they'll have
  254.  * no effect
  255.  */
  256.     curproc->sighandle[SIGTTIN] = curproc->sighandle[SIGTTOU] =
  257.         curproc->sighandle[SIGTSTP] = SIG_IGN;
  258.  
  259. /* set up some more per-process variables */
  260.     curproc->starttime = Tgettime();
  261.     curproc->startdate = Tgetdate();
  262.     if (has_bconmap)
  263.         curproc->bconmap = curbconmap;
  264.     else
  265.         curproc->bconmap = 1;
  266.  
  267.     curproc->logbase = (void *)Logbase();
  268.     curproc->criticerr = *((long ARGS_ON_STACK (**) P_((long)))0x404L);
  269. }
  270.  
  271. /*
  272.  * reset all process priorities to their base level
  273.  * called once per second, so that cpu hogs can get _some_ time
  274.  * slices :-).
  275.  */
  276.  
  277. void
  278. reset_priorities()
  279. {
  280.     PROC *p;
  281.  
  282.     for (p = proclist; p; p = p->gl_next) {
  283.         p->curpri = p->pri;
  284.         p->slices = SLICES(p->curpri);
  285.     }
  286. }
  287.  
  288. /*
  289.  * more priority code stuff:
  290.  * run_next(p, slices): schedule process "p" to run next, with "slices"
  291.  *       initial time slices; "p" does not actually start running until
  292.  *       the next context switch
  293.  * fresh_slices(slices): give the current process "slices" more slices in
  294.  *       which to run
  295.  */
  296.  
  297. void
  298. run_next(p, slices)
  299.     PROC *p;
  300.     int slices;    /* BUG: currently ignored */
  301. {
  302.     UNUSED(slices);
  303.  
  304.     p->slices = 0;
  305.     p->curpri = MAX_NICE;
  306.     p->wait_q = READY_Q;
  307.     p->q_next = sys_q[READY_Q];
  308.     sys_q[READY_Q] = p;
  309. }
  310.  
  311. void
  312. fresh_slices(slices)
  313.     int slices;
  314. {
  315.     curproc->slices = 0;
  316.     curproc->curpri = MAX_NICE+1;
  317.     proc_clock = slices;
  318. }
  319.  
  320. /*
  321.  * add a process to a wait (or ready) queue.
  322.  *
  323.  * processes go onto a queue in first in-first out order
  324.  */
  325.  
  326. void
  327. add_q(que, proc)
  328.     int que;
  329.     PROC *proc;
  330. {
  331.     PROC *q, **lastq;
  332.  
  333. /* "proc" should not already be on a list */
  334.     assert(proc->wait_q == 0);
  335.     assert(proc->q_next == 0);
  336.  
  337.     lastq = &sys_q[que];
  338.     q = *lastq;
  339.     while(q) {
  340.         lastq = &q->q_next;
  341.         q = *lastq;
  342.     }
  343.     *lastq = proc;
  344.     proc->wait_q = que;
  345.     if (que != READY_Q) {
  346.         proc->curpri = proc->pri;    /* reward the process */
  347.         proc->slices = SLICES(proc->curpri);
  348.     }
  349. }
  350.  
  351. /*
  352.  * remove a process from a queue
  353.  */
  354.  
  355. void
  356. rm_q(que, proc)
  357.     int que;
  358.     PROC *proc;
  359. {
  360.     PROC *q;
  361.     PROC *old = 0;
  362.  
  363.     assert(proc->wait_q == que);
  364.  
  365.     q = sys_q[que];
  366.     while (q && q != proc) {
  367.         old = q;
  368.         q = q->q_next;
  369.     }
  370.     if (q == 0)
  371.         FATAL("rm_q: unable to remove process from queue");
  372.  
  373.     if (old)
  374.         old-